// POJ 1325
// Hungarian algorithm
#include <iostream>
using namespace std;

const int N = 109;
const int M = 109;
int n, m;

// 1-start
// g[a][b] is true iff edge (a, b) exists.
// N is left side, M is right side.
bool g[N][M];
bool visited[M];
int match[M];

bool searchPath(int s)
{
	for (int i = 1; i <= m; ++i)
	{
		if (g[s][i] && !visited[i])
		{
			visited[i] = true;
			if (match[i] == 0 || searchPath(match[i]))
			{
				match[i] = s;
				return true;
			}
		}
	}
	return false;
}

void init()
{
	memset(g, 0, sizeof(g));
	memset(match, 0, sizeof(match));
}

int getMatchCount()
{
	int st = 0;
	for (int i = 1; i <= n; ++i)
	{
		memset(visited, 0, sizeof(visited));
		if (searchPath(i))
			++st;
	}
	return st;
}

int main()
{
	while (scanf("%d", &n) && n)
	{
		int k;
		scanf("%d%d", &m, &k);
		init();
		for (int i = 0; i < k; ++i)
		{
			int t, a, b;
			scanf("%d%d%d", &t, &a, &b);
			if (a != 0 && b != 0)
				g[a + 1][b + 1] = true;
		}
		int ans = getMatchCount();
		printf("%d\n", ans);
	}
	system("pause");
	return 0;
}


